﻿
using System.Collections.ObjectModel;
using System.Linq;

namespace Game.Plugin.Parse
{
    public abstract class AbstractPlugin : IGamePlugin
    {
        readonly Collection<IGamePlugin> _Children;
        readonly string _Name;
        readonly IGamePlugin _Parent;

        protected AbstractPlugin(
            IGamePlugin parent, 
            string name)
        {
            _Children = new Collection<IGamePlugin>();
            _Name = name;
            _Parent = parent;
            if (parent != null)
            {
                parent.Children.Add(this);
            }
        }

        public string Name { get { return _Name; } }

        public IGamePlugin Parent { get { return _Parent; } }

        public string Path
        {
            get
            {
                var path = "";
                IGamePlugin p = this;
                while (p != null)
                {
                    if (p.Name != "/" && path.Length > 0)
                    {
                        path = p.Name + "/" + path;
                    }
                    else
                    {
                        path = p.Name + path;
                    }
                    p = p.Parent;
                }
                return path;
            }
        }

        public virtual IGamePlugin Find(string token)
        {
            if (Parent != null)
            {
                if (token == Path)
                {
                    return this;
                }
            }
            else
            {
                if (token == Name)
                {
                    return this;
                }
            }

            foreach (var parser in _Children)
            {
                var result = parser.Find(token);
                if (result != null)
                {
                    return result;
                }
            }

            return null;
        }

        public Collection<IGamePlugin> Children
        {
            get { return _Children; }
        }

        public virtual bool CanParse(string token)
        {
            return (Find(token) == this);
        }

        public virtual bool ChildCanParse(string token)
        {
            return (Find(token) != null);
        }

        public abstract ICodeObject Parse(string token, ParserContext context);

    }
}
